//
//  JYTableBaseAdaptor.m
//  MYCCBRegisterSubAccount
//
//  Created by 应明顺 on 2018/7/4.
//  Copyright © 2018年 JackYing. All rights reserved.
//

#import "JYTableBaseAdaptor.h"
#import "JYBaseTableViewCell.h"
#import "JYBaseHeaderView.h"
#import "JYBaseFooterView.h"


NSInteger const kTagBaseRegContentView = (-10000);
NSInteger const kBaseSection = (1000);


@interface JYTableBaseAdaptor () {
    
    UIView *_selectInput;
    JYBaseCellModel *_selectModel;
}

@property (nonatomic, weak) UITableView *tableView;
@property (nonatomic, strong) NSMutableDictionary *m4cDic; //model for cell Dic
@property (nonatomic, strong) NSMutableDictionary *m4HFDic; //model for headerFooter Dic
@property (nonatomic, strong) NSMutableArray <JYBaseGroupModel *> *dataArr;

@property (nonatomic, strong) NSIndexPath* editingIndexPath;  //当前左滑cell的index，在代理方法中设置

@end

@implementation JYTableBaseAdaptor

- (instancetype)init
{
    if (self = [super init]) {
        mapTabel = [NSMapTable weakToStrongObjectsMapTable];
        self.dataArr = [NSMutableArray array];
        [self regsiterCell];
        [self regsiterSectionHFView];
    }
    return self;
}

+ (instancetype)tableAdaptorWithTableView:(UITableView *)tableView title:(NSString *)title key:(NSString *)key {
    JYTableBaseAdaptor *model = [[self alloc] init];
    model.title = title;
    model.key = key;
    model.tableView = tableView;
    return model;
}

- (void)dealloc {
    NSLog(@"%s" , __func__);
}

- (NSMutableDictionary *)m4cDic {
    if (!_m4cDic) {
        _m4cDic = [NSMutableDictionary dictionary];
    }
    return _m4cDic;
}

- (NSMutableDictionary *)m4HFDic {
    if (!_m4HFDic) {
        _m4HFDic = [NSMutableDictionary dictionary];
    }
    return _m4HFDic;
}

- (void)setDataArr:(NSMutableArray<JYBaseGroupModel *> *)dataArr {
    
    if (_dataArr != dataArr) {
        _dataArr = dataArr;
    }
}

#pragma mark - 共用方法
//--------------------------------------------基础方法-------------------------------------------------
- (JYBaseCellModel *)modelWithItemKey:(NSString *)itemKey {
    // 按二位数组计算
    for (NSInteger i = 0; i < self.dataArr.count; i++) {
        JYBaseGroupModel *group = self.dataArr[i];
        for (NSInteger j = 0; j < group.rowCount; j++) {
            JYBaseCellModel *model = group.rowModelArr[j];
            if ([model.itemKey isEqualToString:itemKey]) {
                return model;
            }
        }
    }
    return nil;
}

- (JYBaseCellModel *)modelWithIndexPath:(NSIndexPath *)indexPath {
    JYBaseGroupModel *groupModel = [self.dataArr objectAtIndex:indexPath.section];
    return [groupModel modelAtIndex:indexPath.row];
}

- (NSIndexPath *)indexPathForModel:(JYBaseCellModel *)model {
    // 按二位数组计算
    NSInteger section = NSIntegerMax, row = NSIntegerMax;
    for (NSInteger i = 0; i < self.dataArr.count; i++) {
        section = i;
        JYBaseGroupModel *groupModel = self.dataArr[section];
        for (NSInteger j = 0; j < groupModel.rowCount; j++) {
            if ([groupModel.rowModelArr[j] isEqual:model]) {
                row = j;
                goto Jump;
            }
        }
    }
Jump:
    return (section == NSIntegerMax || row == NSIntegerMax) ? nil : [NSIndexPath indexPathForRow:row inSection:section];
}

- (NSIndexPath *)indexOfLeadModelForClass:(Class)modelClass {
    // 按二位数组计算
    NSInteger section = NSIntegerMax, row = NSIntegerMax;
    for (NSInteger i = 0; i < self.dataArr.count; i++) {
        section = i;
        JYBaseGroupModel *groupModel = self.dataArr[section];
        for (NSInteger j = 0; j < groupModel.rowCount; j++) {
            if ([groupModel.rowModelArr[j] isKindOfClass:modelClass]) {
                row = j;
                goto Jump;
            }
        }
    }
Jump:
    return (section == NSIntegerMax || row == NSIntegerMax) ? nil : [NSIndexPath indexPathForRow:row inSection:section];
}

- (NSIndexPath *)indexPathForModelItemKey:(NSString *)itemKey {
    return [self indexPathForModel:[self modelWithItemKey:itemKey]];
}

- (NSIndexPath *)indexPathForInputView:(UIView *)inputView {
    NSInteger tag = inputView.tag - kTagBaseRegContentView;
    NSInteger section = tag / kBaseSection, row = tag % kBaseSection;
    return [NSIndexPath indexPathForRow:row inSection:section];
}

- (NSInteger)tagForInputViewWithIndexPath:(NSIndexPath *)indexPath {
    return kTagBaseRegContentView + indexPath.section * kBaseSection + indexPath.row;
}

- (UIView *)inputViewForIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    return [cell viewWithTag:[self tagForInputViewWithIndexPath:indexPath]];
}

- (void)regsiterCell {
    [self regsiterCell:[JYBaseTableViewCell class] forModelClass:[JYBaseCellModel class]];
}

/**
 在tv中用model类型注册对应类型的cell
 
 @param cellClass model class
 @param mClazz model class
 */
- (void)regsiterCell:(Class)cellClass forModelClass:(Class)mClazz {
    
    NSString *newKey = NSStringFromClass(mClazz);
    /// !!:一种model对应一种cell。一种cell可以对应中model
    NSAssert(![self.m4cDic.allKeys containsObject:newKey], @"tableView 中已经注册了相应的cell");
    NSAssert([cellClass isSubclassOfClass:[UITableViewCell class]], @"cellClass 不是UITableViewCell子类");
    
    [self.m4cDic setObject:cellClass forKey:newKey];
    // register与dequeue对应，以便dequeue时可以使用indexPath，
    // TODO: 解决cell刷新时再次创建消耗性能的问题
    [self.tableView registerClass:cellClass forCellReuseIdentifier:NSStringFromClass(cellClass)];
}

- (void)regsiterCellNib:(Class)cellNibClass forModelClass:(Class)mClazz {
    
    NSString *newKey = NSStringFromClass(mClazz);
    NSAssert(![self.m4cDic.allKeys containsObject:newKey], @"tableView 中已经注册了相应的cell");
    NSString *nibName = NSStringFromClass(cellNibClass);
    UINib *nib = [UINib nibWithNibName:nibName bundle:nil];
    
    [self.m4cDic setObject:nib forKey:newKey];
    [self.tableView registerNib:nib forCellReuseIdentifier:newKey];
}

- (void)regsiterSectionHFView {
    [self regsiterSectionHFView:[JYBaseHeaderView class] forModelClass:[JYBaseHeaderModel class]];
    [self regsiterSectionHFView:[JYBaseFooterView class] forModelClass:[JYBaseFooterModel class]];
}

- (void)regsiterSectionHFView:(Class)hfClass forModelClass:(Class)mClazz {
    NSString *newKey = NSStringFromClass(mClazz);
    /// !!:一种model对应一种cell。一种cell可以对应中model
    NSAssert(![self.m4HFDic.allKeys containsObject:newKey], @"tableView 中已经注册了相应的cell");
    NSAssert([hfClass isSubclassOfClass:[UITableViewHeaderFooterView class]], @"cellClass 不是UITableViewCell子类");
    
    [self.m4HFDic setObject:hfClass forKey:newKey];
    [self.tableView registerClass:hfClass forHeaderFooterViewReuseIdentifier:newKey];
}

#pragma mark - 数据源控制
//--------------------------------------------数据源控制-------------------------------------------------
- (JYTableBaseAdaptor *)appendGroup:(JYBaseGroupModel *)groupModel {
    if (groupModel) {
        [self.dataArr addObject:groupModel];
    }
    [self.tableView reloadData];
    return self;
}

- (JYTableBaseAdaptor *)insertGroup:(JYBaseGroupModel *)groupModel atIndex:(NSInteger)index {
    if (groupModel && index < self.dataArr.count) {
        [self.dataArr insertObject:groupModel atIndex:index];
    }
    [self.tableView reloadData];
    return self;
}

- (JYBaseGroupModel *)deleteGroupAtIndex:(NSInteger)index {
    JYBaseGroupModel *groupModel;
    if (groupModel && index < self.dataArr.count) {
        groupModel = [self.dataArr objectAtIndex:index];
        [self.dataArr removeObjectAtIndex:index];
    }
    [self.tableView reloadData];
    return groupModel;
}

//--------------------------------------------TableView回调-------------------------------------------------
#pragma mark - <UITableViewDataSource>
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSInteger group = self.dataArr.count;
    return group;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger rows = self.dataArr[section].rowCount;
    return rows;
}

/*
 该方法可以在子类中进行重写
 此处进行通用配置，如需其他配置可以继承该类后在对cell进行设置
 在自定义cell.contentV时需要先对contentV进行赋值在对model进行赋值，否则数据不生效
 */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    JYBaseCellModel *model = [self modelWithIndexPath:indexPath];
    Class cClass = [self.m4cDic objectForKey:NSStringFromClass([model class])];
    
    JYBaseTableViewCell *cell = nil;
    if ([cClass isKindOfClass:[UINib class]]) {// 对nib方式适配
        cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([model class])];
    } else {
        if (!cClass) {// 未注册类，默认为JYBaseRegTableViewCell
            cClass = [JYBaseTableViewCell class];
        }
        cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(cClass) forIndexPath:indexPath];
        if (!cell) {
            cell = [[cClass alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:NSStringFromClass(cClass)];
        }
    }
    
    // 此处设置tag在indexPathForInputView中会用到
    cell.model = model;
    cell.accessoryAction = self.cellAccessoryAction;
    cell.contentV.tag = [self tagForInputViewWithIndexPath:indexPath];
    
    return cell;
}


#pragma mark - <UITableViewDelegate>
//////////////////////////////  CELL  //////////////////////////////
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (self.cellSelectedAction) {
        self.cellSelectedAction(indexPath, self, [self modelWithIndexPath:indexPath]);
    }
}


// 该方法可以在子类中进行重写
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    JYBaseCellModel *model = [self modelWithIndexPath:indexPath];
    if (mapTabel && !model.contentUpdated) {
        /// !!:不能使用indexPath做key。否则在表头添加数据时，高度不能重新获取到新数据的高度
        NSNumber *heightNum = [mapTabel objectForKey:model];
        if (heightNum) {
            return [heightNum floatValue];
        }
    }

    // 预估高度为0时相当于隐藏当前cell
    CGFloat height = model.estimatedHeight;
    [mapTabel setObject:@(height) forKey:model];
    return height;
}


////////////////////////  HeaderFooter  ////////////////////////
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    JYBaseHeaderModel *headerModel = self.dataArr[section].headerModel;
    if (headerModel == nil) {
        return nil;
    }
    Class cClass = [self.m4HFDic objectForKey:NSStringFromClass([headerModel class])];
    if (!cClass) {// 未注册类，默认为JYBaseHeaderView
        cClass = [JYBaseHeaderView class];
    }
    JYBaseHeaderView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass(cClass)];
    if (!header) {
        header = [[cClass alloc] initWithReuseIdentifier:NSStringFromClass(cClass)];
    }
    header.headerModel = headerModel;
    return header;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    
    CGFloat estimatedHeight = self.dataArr[section].headerModel.estimatedHeight;
    estimatedHeight = estimatedHeight ? estimatedHeight : 0.00001;
    return estimatedHeight;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    
    JYBaseFooterModel *footerModel = self.dataArr[section].footerModel;
    if (footerModel == nil) {
        return nil;
    }
    Class cClass = [self.m4HFDic objectForKey:NSStringFromClass([footerModel class])];
    if (!cClass) {// 未注册类，默认为JYBaseFooterView
        cClass = [JYBaseFooterView class];
    }
    JYBaseFooterView *footer = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass(cClass)];
    if (!footer) {
        footer = [[cClass alloc] initWithReuseIdentifier:NSStringFromClass(cClass)];
    }
    footer.model = self.dataArr[section].footerModel;
    footer.nextAction = self.nextAcvtion;
    return footer;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    //return self.dataArr[section].footerModel.estimatedHeight + 20; // + 20：设置最后一组与下一步的间距
    CGFloat estimatedHeight = self.dataArr[section].footerModel.estimatedHeight;
    estimatedHeight = estimatedHeight ? estimatedHeight : 0.00001;
    if (estimatedHeight < 1 && section != self.dataArr.count - 1) {
        return 20;// 分段预留间距
    }
    return estimatedHeight;
}


#pragma mark - Edit-Swipe
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    if (self.cellEditable) {
        return self.cellEditable(indexPath, self);
    } else {
        return NO;
    }
}

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (self.cellEditAction) {
        JYBaseCellModel *model = [self modelWithIndexPath:indexPath];
        return self.cellEditAction(indexPath, self, model);
    } else {
        return nil;
    }
}

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.editingIndexPath = indexPath;
    // 触发-(void)viewDidLayoutSubviews
    [((UIViewController *)[self.tableView.superview nextResponder]).view setNeedsLayout];
}

- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.editingIndexPath = nil;
}





@end
